package com.intelligent.eayon.utils;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.intelligent.eayon.dto.AttrDto;
import com.intelligent.eayon.dto.RequestDto;
import com.intelligent.eayon.dto.ResponseDto;
import com.intelligent.eayon.message.*;
import com.intelligent.ispc.common.utils.ApplicationException;
import com.intelligent.ispc.common.utils.ExceptionMessages;
import com.intelligent.ispc.common.utils.StringUtils;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Map;

public class MessageUtils {

    private static Logger logger = LoggerFactory.getLogger(MessageUtils.class);

    /**
     * checksum
     *
     * @param bytes bytes
     * @return the result of check
     */
    public static boolean checksum(byte[] bytes) {

        int length = bytes.length;
        byte sum = 0;
        for (int i = 0; i < length - 1; i++) {
            sum += bytes[i];
        }

        if (sum == bytes[length - 1]) {
            return true;
        } else {
            return false;
        }
    }

//    public static Attr attrEncoder() {
//
//    }

    /**
     * requestEncoder
     *
     * @param in in
     * @return Request
     */
    public static Request requestDecoder(byte[] in) {

        try {
            if (in.length < 8) {
                logger.error("requestDecoder error.");
//                throw new ApplicationException(ExceptionMessages.ERR_19002);
            }

            Request out = new Request();

            int length = in.length;
            ByteBuf buf = Unpooled.buffer(length);
            buf.writeBytes(in);

            out.setCode(buf.readBytes(4).array());
            out.setAtlg(buf.readBytes(4).array());

            int len = ByteUtils.bytes2int(out.getAtlg());
            if (buf.readableBytes() != len) {
                logger.error("requestDecoder error.");
//                throw new ApplicationException(ExceptionMessages.ERR_19002);
            }
            out.setAttr(buf.readBytes(len).array());
            return out;
        } catch (Exception e) {
            if (!(e instanceof ApplicationException)) {
                e.printStackTrace();
            }
            throw new ApplicationException(ExceptionMessages.ERR_90001);
        }
    }

    /**
     * requestEncoder
     *
     * @param in in
     * @return byte[]
     */
    public static byte[] requestEncoder(Request in) {
        try {
            if (in == null) {
                logger.error("requestEncoder invalid input.");
                throw new ApplicationException(ExceptionMessages.ERR_13001);
            }
            if (in.length() < 8) {
                logger.error("requestEncoder error.");
//                throw new ApplicationException(ExceptionMessages.ERR_19004);
            }

            int length = in.length();

            ByteBuf buf = Unpooled.buffer(length);

            buf.writeBytes(in.getCode());
            buf.writeBytes(in.getAtlg());

            int len = ByteUtils.bytes2int(in.getAtlg());

            if (in.getAttr() != null) {
                if (len != in.getAttr().length) {
                    logger.error("requestEncoder error.");
                    throw new ApplicationException(ExceptionMessages.ERR_90001);
                }

                if (len != 0) {
                    buf.writeBytes(in.getAttr());
                }
            }

            return buf.array();
        } catch (Exception e) {
            if (e instanceof ApplicationException) {
                throw new ApplicationException(((ApplicationException) e).getCode());
            } else {
                e.printStackTrace();
                throw new ApplicationException(ExceptionMessages.ERR_90001);
            }
        }

    }

    /**
     * requestDtoDecoder
     *
     * @param in in
     * @return RequestDto
     */
    public static RequestDto requestDtoDecoder(Request in) {
        try {
            if (in == null) {
                logger.error("requestDtoDecoder invalid input.");
                throw new ApplicationException(ExceptionMessages.ERR_13001);
            }

            RequestDto out = new RequestDto();

            out.setCode(ByteUtils.bytes2int(in.getCode()));
            out.setAtlg(ByteUtils.bytes2int(in.getAtlg()));

            List<Attr> attr = attrDecoder(in.getAttr());
            if (attr == null || attr.size() == 0) {
                out.setAttr(null);
            } else {
                List<AttrDto> attrDto = attrDtosDecoder(attr);
                out.setAttr(attrDto);
            }

            return out;
        } catch (Exception e) {
            if (e instanceof ApplicationException) {
                throw new ApplicationException(((ApplicationException) e).getCode());
            } else {
                e.printStackTrace();
                throw new ApplicationException(ExceptionMessages.ERR_20001);
            }
        }
    }

    /**
     * requestDtoEncoder
     *
     * @param in in
     * @return Request
     * @throws UnsupportedEncodingException unsupportedEncodingException
     */
    public static Request requestDtoEncoder(RequestDto in) throws UnsupportedEncodingException {
        try {
            if (in == null) {
                logger.error("requestDtoEncoder invalid input.");
                throw new ApplicationException(ExceptionMessages.ERR_13001);
            }
            Request request = new Request();

            request.setCode(ByteUtils.intToBytes(in.getCode()));
            request.setAtlg(ByteUtils.intToBytes(in.getAtlg()));

            if (in.getAtlg() != 0) {
                List<Attr> attr = attrDtosEncoder(in.getAttr());
                byte[] attrByte = attrEncoder(attr);
                request.setAttr(attrByte);
            }

            return request;
        } catch (Exception e) {
            if (e instanceof ApplicationException) {
                throw new ApplicationException(((ApplicationException) e).getCode());
            } else {
                e.printStackTrace();
                throw new ApplicationException(ExceptionMessages.ERR_20001);
            }
        }
    }

    /**
     * requestEncoder
     *
     * @param in in
     * @return Response
     */
    public static Response responseDecoder(byte[] in) {
        try {
            if (in.length < 12) {
                logger.error("responseDecoder error.");
//                throw new ApplicationException(ExceptionMessages.ERR_19005);
            }
            Response out = new Response();

            int length = in.length;
            ByteBuf buf = Unpooled.buffer(length);
            buf.writeBytes(in);

            out.setCode(buf.readBytes(4).array());
            out.setErrc(buf.readBytes(4).array());
            out.setAtlg(buf.readBytes(4).array());

            int len = ByteUtils.bytes2int(out.getAtlg());
            if (buf.readableBytes() != len) {
                logger.error("responseDecoder error.");
//                throw new ApplicationException(ExceptionMessages.ERR_19005);
            }
            out.setAttr(buf.readBytes(len).array());

            return out;
        } catch (Exception e) {
            if (!(e instanceof ApplicationException)) {
                e.printStackTrace();
            }
            throw new ApplicationException(ExceptionMessages.ERR_90001);
        }
    }

    /**
     * requestEncoder
     *
     * @param in in
     * @return byte[]
     */
    public static byte[] responseEncoder(Response in) {
        try {
            if (in == null) {
                logger.error("responseEncoder invalid input.");
                throw new ApplicationException(ExceptionMessages.ERR_13001);
            }
            if (in.length() < 12) {
                logger.error("responseEncoder error.");
//                throw new ApplicationException(ExceptionMessages.ERR_19006);
            }

            int length = in.length();

            ByteBuf buf = Unpooled.buffer(length);

            buf.writeBytes(in.getCode());
            buf.writeBytes(in.getErrc());
            buf.writeBytes(in.getAtlg());

            int len = ByteUtils.bytes2int(in.getAtlg());

            if (in.getAttr() != null) {
                if (len != in.getAttr().length) {
                    logger.error("responseEncoder error.");
//                    throw new ApplicationException(ExceptionMessages.ERR_19006);
                }

                if (len != 0) {
                    buf.writeBytes(in.getAttr());
                }
            }

            return buf.array();
        } catch (Exception e) {
            if (e instanceof ApplicationException) {
                throw new ApplicationException(((ApplicationException) e).getCode());
            } else {
                e.printStackTrace();
                throw new ApplicationException(ExceptionMessages.ERR_90001);
            }
        }
    }

    /**
     * requestDtoDecoder
     *
     * @param in in
     * @return ResponseDto
     */
    public static ResponseDto responseDtoDecoder(Response in) {
        try {
            if (in == null) {
                logger.error("responseDtoDecoder invalid input.");
                throw new ApplicationException(ExceptionMessages.ERR_13001);
            }

            ResponseDto out = new ResponseDto();

            out.setCode(ByteUtils.bytes2int(in.getCode()));
            out.setErrc(ByteUtils.bytes2int(in.getErrc()));
            out.setAtlg(ByteUtils.bytes2int(in.getAtlg()));

            int len = ByteUtils.bytes2int(in.getAtlg());
            if (len != 0) {
                out.setAttr(attrDtosDecoder(attrDecoder(in.getAttr())));
            }

            return out;
        } catch (Exception e) {
            if (e instanceof ApplicationException) {
                throw new ApplicationException(((ApplicationException) e).getCode());
            } else {
                e.printStackTrace();
                throw new ApplicationException(ExceptionMessages.ERR_20001);
            }
        }

    }

    /**
     * requestDtoEncoder
     *
     * @param in in
     * @return Response
     * @throws UnsupportedEncodingException unsupportedEncodingException
     */
    public static Response responseDtoEncoder(ResponseDto in) throws UnsupportedEncodingException {
        try {
            if (in == null) {
                logger.error("requestDtoEncoder invalid input.");
                throw new ApplicationException(ExceptionMessages.ERR_13001);
            }
            Response response = new Response();

            response.setCode(ByteUtils.intToBytes(in.getCode()));
            response.setErrc(ByteUtils.intToBytes(in.getErrc()));
            response.setAtlg(ByteUtils.intToBytes(in.getAtlg()));

            int len = in.getAtlg();
            if (len != 0) {
                response.setAttr(attrEncoder(attrDtosEncoder(in.getAttr())));
            }

            return response;
        } catch (Exception e) {
            if (e instanceof ApplicationException) {
                throw new ApplicationException(((ApplicationException) e).getCode());
            } else {
                e.printStackTrace();
                throw new ApplicationException(ExceptionMessages.ERR_20001);
            }
        }

    }


    /**
     * requestEncoder
     *
     * @param in in
     * @return List<Attr>
     */
    public static List<Attr> attrDecoder(byte[] in) {
        try {
            if (in == null) {
                logger.error("attrDecoder invalid input.");
                throw new ApplicationException(ExceptionMessages.ERR_13001);
            }
            List<Attr> result = Lists.newArrayList();

            int length = in.length;
            ByteBuf buf = Unpooled.buffer(length);
            buf.writeBytes(in);

            int start = 0;
            while (buf.isReadable()) {
                Attr attr = new Attr();
                int anlg = buf.getInt(start);
                attr.setEqlg(buf.readBytes(4).array());
                attr.setEqid(buf.readBytes(anlg).array());
                int lolg = buf.getInt(start + 12 + anlg);
     //           attr.setLovl(buf.readBytes(lolg).array());
                start += 16;
                start += anlg;
                start += lolg;

                result.add(attr);
            }
            return result;
        } catch (Exception e) {
            if (e instanceof ApplicationException) {
                throw new ApplicationException(((ApplicationException) e).getCode());
            } else {
                e.printStackTrace();
                throw new ApplicationException(ExceptionMessages.ERR_11001);
            }
        }

    }

    /**
     * requestEncoder
     *
     * @param in in
     * @return byte[]
     */
    public static byte[] attrEncoder(List<Attr> in) {
        try {
            if (in == null || in.size() == 0) {
                logger.error("attrEncoder invalid input.");
                throw new ApplicationException(ExceptionMessages.ERR_13001);
            }
            int length = 0;
            for (Attr attr : in) {
                length += attr.length();
            }
            ByteBuf buf = Unpooled.buffer(length);
            for (Attr attr : in) {
                buf.writeBytes(attr.getEqlg());

                int len = ByteUtils.bytes2int(attr.getEqlg());

                if (len != 0) {
                    buf.writeBytes(attr.getEqid());
                }
            }


            return buf.array();
        } catch (Exception e) {
            if (e instanceof ApplicationException) {
                throw new ApplicationException(((ApplicationException) e).getCode());
            } else {
                e.printStackTrace();
                throw new ApplicationException(ExceptionMessages.ERR_20001);
            }
        }

    }

    /**
     * requestDtoDecoder
     *
     * @param in in
     * @return List<AttrDto>
     */
    public static List<AttrDto> attrDtosDecoder(List<Attr> in) {
        try {
            if (in == null || in.size() == 0) {
                logger.error("attrDtosDecoder invalid input.");
                throw new ApplicationException(ExceptionMessages.ERR_13001);
            }
            List<AttrDto> out = Lists.newArrayList();

            for (Attr attr : in) {
                AttrDto attrDto = attrDtoDecoder(attr);
                out.add(attrDto);
            }

            return out;
        } catch (Exception e) {
            if (e instanceof ApplicationException) {
                throw new ApplicationException(((ApplicationException) e).getCode());
            } else {
                e.printStackTrace();
                throw new ApplicationException(ExceptionMessages.ERR_20001);
            }
        }

    }

    /**
     * attrDtoDecoder
     *
     * @param in in
     * @return AttrDto
     */
    public static AttrDto attrDtoDecoder(Attr in) {
        try {
            if (in == null) {
                logger.error("attrDtoDecoder invalid input.");
                throw new ApplicationException(ExceptionMessages.ERR_13001);
            }
            AttrDto attrDto = new AttrDto();
            attrDto.setEqlg(ByteUtils.bytes2int(in.getEqlg()));
            attrDto.setEqid(new String(in.getEqid()));
            return attrDto;
        } catch (Exception e) {
            if (e instanceof ApplicationException) {
                throw new ApplicationException(((ApplicationException) e).getCode());
            } else {
                e.printStackTrace();
                throw new ApplicationException(ExceptionMessages.ERR_20001);
            }
        }

    }

    /**
     * attrDtosEncoder
     *
     * @param in in
     * @return Attr
     * @throws UnsupportedEncodingException unsupportedEncodingException
     */
    public static Attr attrDtoEncoder(AttrDto in) throws UnsupportedEncodingException {
        try {
            if (in == null) {
                logger.error("attrDtoEncoder invalid input.");
                throw new ApplicationException(ExceptionMessages.ERR_13001);
            }
            Attr attr = new Attr();

            attr.setEqlg(ByteUtils.intToBytes(in.getEqlg()));

            if (StringUtils.isNotBlank(in.getEqid())) {
                attr.setEqid(in.getEqid().getBytes("UTF-8"));
            }

            return attr;
        } catch (Exception e) {
            if (e instanceof ApplicationException) {
                throw new ApplicationException(((ApplicationException) e).getCode());
            } else {
                e.printStackTrace();
                throw new ApplicationException(ExceptionMessages.ERR_20001);
            }
        }

    }

    /**
     * requestDtoEncoder
     *
     * @param in in
     * @return List<Attr>
     * @throws UnsupportedEncodingException unsupportedEncodingException
     */
    public static List<Attr> attrDtosEncoder(List<AttrDto> in) throws UnsupportedEncodingException {
        try {
            if (in == null || in.size() == 0) {
                logger.error("attrDtosEncoder invalid input.");
                throw new ApplicationException(ExceptionMessages.ERR_13001);
            }
            List<Attr> attrs = Lists.newArrayList();

            for (AttrDto attrDto : in) {
                Attr attr = attrDtoEncoder(attrDto);
                attrs.add(attr);
            }

            return attrs;
        } catch (Exception e) {
            if (e instanceof ApplicationException) {
                throw new ApplicationException(((ApplicationException) e).getCode());
            } else {
                e.printStackTrace();
                throw new ApplicationException(ExceptionMessages.ERR_20001);
            }
        }

    }

    /**
     * ipEncoder
     *
     * @param in in
     * @return String
     */
    public static String ipEncoder(byte[] in) {
        try {
            if (in.length != 4) {
                logger.error("ipEncoder invalid input.");
                throw new ApplicationException(ExceptionMessages.ERR_13001);
            }

            StringBuffer stringBuffer = new StringBuffer();

            for (int i = 0; i < 4; i++) {
                byte[] bytes = new byte[2];
                bytes[0] = 0;
                bytes[1] = in[i];
                short s = ByteUtils.bytesToShort(bytes);
                stringBuffer.append(s + ".");
            }

            return stringBuffer.substring(0, stringBuffer.length() - 1);
        } catch (Exception e) {
            if (e instanceof ApplicationException) {
                throw new ApplicationException(((ApplicationException) e).getCode());
            } else {
                e.printStackTrace();
                throw new ApplicationException(ExceptionMessages.ERR_20001);
            }
        }

    }

    /**
     * ipEncoder
     *
     * @param in in
     * @return byte[]
     */
    public static byte[] ipEncoder(String in) {

        try {
            if (StringUtils.isBlank(in)) {
                logger.error("ipEncoder invalid input.");
                throw new ApplicationException(ExceptionMessages.ERR_13001);
            }

            String[] v = in.split("\\.");

            int length = 4;
            ByteBuf buf = Unpooled.buffer(length);

            buf.writeByte((byte) (Short.parseShort(v[0])));
            buf.writeByte((byte) (Short.parseShort(v[1])));
            buf.writeByte((byte) (Short.parseShort(v[2])));
            buf.writeByte((byte) (Short.parseShort(v[3])));

            return buf.array();
        } catch (Exception e) {
            if (e instanceof ApplicationException) {
                throw new ApplicationException(((ApplicationException) e).getCode());
            } else {
                e.printStackTrace();
                throw new ApplicationException(ExceptionMessages.ERR_20001);
            }
        }
    }

    /**
     * build ReturnMsg
     *
     * @param response response
     * @return TransMessage
     * @throws UnsupportedEncodingException Exception
     */
    public static TransMessage buidReturnMsg(Response response) throws UnsupportedEncodingException {
        try {

            if (response == null) {
                logger.error("attrDtosEncoder invalid input.");
                throw new ApplicationException(ExceptionMessages.ERR_13001);
            }

            TransMessage message = new TransMessage();
            MessageHead head = new MessageHead();
            MessageBody body = new MessageBody();

            head.setVern("V1.0".getBytes("UTF-8"));
            head.setSeqn(ByteUtils.intToBytes(0));
            head.setCtnf((byte) 0);
            head.setPakn(ByteUtils.intToBytes(0));

            byte[] timp = new byte[16];
//        long timps = System.currentTimeMillis();

            head.setTimp(timp);

            byte[] msid = new byte[32];
            for (int i = 0; i < 32; i++) {
                msid[i] = (byte) 11;
            }
            head.setMsid(msid);

            byte[] errc = new byte[6];
            for (int i = 0; i < 6; i++) {
                errc[i] = (byte) 0;
            }

            head.setErrc(errc);
            head.setMspr(ByteUtils.shortToBytes((short) 1));
            head.setHcs((byte) 11);

            message.setHead(head);

            byte[] data = responseEncoder(response);
            head.setMslg(ByteUtils.intToBytes(data.length + 1));

            body.setData(data);
            body.setDcs((byte) 11);

            message.setBody(body);


            byte[] byteMessage = encode(message);
            Map<String, Byte> result = transMessageCheckSum(byteMessage);
            message.getHead().setHcs(result.get("HEAD"));
            message.getBody().setDcs(result.get("BODY"));

            return message;
        } catch (Exception e) {
            if (e instanceof ApplicationException) {
                throw new ApplicationException(((ApplicationException) e).getCode());
            } else {
                e.printStackTrace();
                throw new ApplicationException(ExceptionMessages.ERR_20001);
            }
        }
    }

    private static byte sum(byte[] in) {
        int length = in.length;
        byte result = 0;
        for (int i = 0; i < length; i++) {
            result += in[i];
        }
        return result;
    }


    /**
     * message encode
     *
     * @param message message
     * @return byte[]
     */
    public static byte[] encode(TransMessage message) {

        int length = ByteUtils.bytes2int(message.getHead().getMslg());

        int buflen = length + 75;

        ByteBuf out = Unpooled.buffer(buflen);

        out.writeBytes(message.getHead().getVern());
        out.writeBytes(message.getHead().getSeqn());
        out.writeByte(message.getHead().getCtnf());
        if (message.getHead().getCtnf() != 0) {
            out.writeBytes(message.getHead().getPakn());
        }
        out.writeBytes(message.getHead().getTimp());
        out.writeBytes(message.getHead().getMsid());
        out.writeBytes(message.getHead().getErrc());
        out.writeBytes(message.getHead().getMspr());
        out.writeBytes(message.getHead().getMslg());
        out.writeByte(message.getHead().getHcs());

        if (message.getBody().getData() != null) {
            out.writeBytes(message.getBody().getData());
        }

        out.writeByte(message.getBody().getDcs());

        return out.array();
    }

    /**
     * transMessage CheckSum
     *
     * @param msg byte[]
     * @return Map<String, Byte>
     */
    private static Map<String, Byte> transMessageCheckSum(byte[] msg) {

        Map<String, Byte> result = Maps.newHashMap();

        ByteBuf in = Unpooled.buffer(msg.length);

        in.writeBytes(msg);
        if (in.getByte(8) != 0) {
            byte[] head = new byte[73];
            in.getBytes(0, head);
            result.put("HEAD", sum(head));

            int msgLength = in.getInt(69);

            byte[] body = new byte[msgLength - 1];
            in.getBytes(74, body);
            result.put("BODY", sum(body));

        } else {
            byte[] head = new byte[69];
            in.getBytes(0, head);
            result.put("HEAD", sum(head));

            int msgLength = in.getInt(65);

            byte[] body = new byte[msgLength - 1];
            in.getBytes(70, body);
            result.put("BODY", sum(body));
        }
        return result;

    }

    private static boolean isInit(byte[] in) {

        for (int i = 0; i < in.length; i++) {
            if (in[i] != 0) {
                return false;
            }
        }
        return true;
    }

    /**
     * build TransMessage
     *
     * @param messageHead MessageHead
     * @param response    Object
     * @return TransMessage
     * @throws UnsupportedEncodingException Exception
     */
    public static TransMessage buildTransMessage(MessageHead messageHead, Object response) throws UnsupportedEncodingException {
        try {
            TransMessage message = new TransMessage();
            MessageHead head = new MessageHead();
            MessageBody body = new MessageBody();

            if (messageHead != null && !isInit(messageHead.getVern())) {
                head.setVern(messageHead.getVern());
            } else {
                head.setVern("V1.0".getBytes("UTF-8"));
            }
            if (messageHead != null && !isInit(messageHead.getSeqn())) {
                head.setSeqn(messageHead.getSeqn());
            } else {
                head.setSeqn(ByteUtils.intToBytes(0));
            }
            if (messageHead == null || messageHead.getCtnf() == 0) {
                head.setCtnf((byte) 0);
            } else {
                head.setCtnf(messageHead.getCtnf());
            }
//        head.setPakn(ByteUtils.intToBytes(0));

            //&& !StringUtils.isBlank(new String(messageHead.getTimp()))
            if (messageHead != null && !isInit(messageHead.getTimp())) {
                head.setTimp(messageHead.getTimp());
            } else {
                byte[] timp = new byte[16];
                long timps = System.currentTimeMillis();

                head.setTimp(timp);
            }

            if (messageHead != null && !isInit(messageHead.getMsid())) {
                head.setMsid(messageHead.getMsid());
            } else {
                byte[] msid = new byte[32];
                for (int i = 0; i < 32; i++) {
                    msid[i] = (byte) 11;
                }
                head.setMsid(msid);
            }

            // !StringUtils.isBlank(new String(messageHead.getErrc()))  &&
            if (messageHead != null && !isInit(messageHead.getErrc())) {
                head.setErrc(messageHead.getErrc());
            } else {
                byte[] errc = new byte[6];
                for (int i = 0; i < 6; i++) {
                    errc[i] = (byte) 0;
                }

                head.setErrc(errc);
            }

            if (messageHead == null || ByteUtils.bytesToShort(messageHead.getMspr()) == 0) {
                head.setMspr(ByteUtils.shortToBytes((short) 1));
            } else {
                head.setMspr(messageHead.getMspr());
            }

            if (messageHead == null || messageHead.getHcs() == 0) {
                head.setHcs((byte) 11);
            } else {
                head.setHcs(messageHead.getHcs());
            }

            message.setHead(head);

            byte[] data = null;
            if (response != null) {
                if (response instanceof Response) {
                    Response response1 = (Response) response;
                    data = responseEncoder(response1);
                } else {
                    data = requestEncoder((Request) response);
                }

                head.setMslg(ByteUtils.intToBytes(data.length + 1));
                body.setData(data);
            } else {
                head.setMslg(ByteUtils.intToBytes(1));
            }

            body.setDcs((byte) 11);

            message.setBody(body);

            byte[] byteMessage = encode(message);
            Map<String, Byte> result = transMessageCheckSum(byteMessage);
            message.getHead().setHcs(result.get("HEAD"));
            message.getBody().setDcs(result.get("BODY"));

            return message;
        } catch (Exception e) {
            if (e instanceof ApplicationException) {
                throw new ApplicationException(((ApplicationException) e).getCode());
            } else {
                e.printStackTrace();
                throw new ApplicationException(ExceptionMessages.ERR_20001);
            }
        }

    }

    /**
     * attrListLength
     *
     * @param attrDtos attrDtos
     * @return int
     * @throws UnsupportedEncodingException unsupportedEncodingException
     */
    public static int attrListLength(List<AttrDto> attrDtos) throws UnsupportedEncodingException {
        try {
            if (attrDtos == null || attrDtos.size() == 0) {
                logger.error("attrDtosEncoder invalid input.");
                throw new ApplicationException(ExceptionMessages.ERR_13001);
            }
            List<Attr> attrs = attrDtosEncoder(attrDtos);

            int result = 0;

            for (Attr attr : attrs) {
                result += attr.length();
            }
            return result;
        } catch (Exception e) {
            if (e instanceof ApplicationException) {
                throw new ApplicationException(((ApplicationException) e).getCode());
            } else {
                e.printStackTrace();
                throw new ApplicationException(ExceptionMessages.ERR_20001);
            }
        }
    }
}